<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>学生管理系统 - 实验中心</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/axios@0.21.1/dist/axios.min.js"></script>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
        }

        body {
            background: #f5f7fa;
            min-height: 100vh;
            display: flex;
            flex-direction: column;
            color: #333;
        }

        .navbar {
            display: flex;
            justify-content: space-between;
            align-items: center;
            background: linear-gradient(135deg, #2c3e50, #1a2530);
            color: white;
            padding: 15px 30px;
            position: relative;
            z-index: 100;
            box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
        }

        .logo-container {
            display: flex;
            align-items: center;
            gap: 15px;
        }

        .logo-container img {
            height: 45px;
            filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.3));
        }

        .logo-container h1 {
            font-size: 1.8rem;
            font-weight: 600;
            color: white;
        }

        .user-info-container {
            display: flex;
            align-items: center;
            gap: 20px;
            position: relative;
        }

        .user-avatar {
            width: 50px;
            height: 50px;
            border-radius: 50%;
            background: #3498db;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 1.5rem;
            font-weight: bold;
            color: white;
            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
            cursor: pointer;
            transition: all 0.3s ease;
        }

        .user-avatar:hover {
            transform: scale(1.05);
            background: #2980b9;
        }

        .dropdown-menu {
            position: absolute;
            top: 65px;
            right: 0;
            background: white;
            border-radius: 8px;
            box-shadow: 0 5px 15px rgba(0, 0, 0, 0.15);
            width: 220px;
            overflow: hidden;
            z-index: 1000;
            display: none;
        }

        .dropdown-menu.show {
            display: block;
        }

        .dropdown-header {
            padding: 15px;
            background: #f8f9fa;
            border-bottom: 1px solid #eee;
        }

        .dropdown-header h4 {
            font-size: 1.1rem;
            color: #2c3e50;
            margin-bottom: 5px;
        }

        .dropdown-header p {
            font-size: 0.9rem;
            color: #777;
        }

        .dropdown-item {
            padding: 12px 20px;
            display: flex;
            align-items: center;
            gap: 10px;
            cursor: pointer;
            transition: all 0.2s ease;
            color: #555;
        }

        .dropdown-item:hover {
            background: #f0f7ff;
            color: #3498db;
        }

        .dropdown-item i {
            width: 20px;
            text-align: center;
        }

        .dropdown-divider {
            height: 1px;
            background: #eee;
            margin: 5px 0;
        }

        .logout-btn {
            background: rgba(255, 255, 255, 0.15);
            color: white;
            border: 1px solid rgba(255, 255, 255, 0.3);
            padding: 8px 18px;
            border-radius: 20px;
            cursor: pointer;
            font-weight: 500;
            transition: all 0.3s ease;
            display: flex;
            align-items: center;
            gap: 8px;
        }

        .logout-btn:hover {
            background: rgba(255, 255, 255, 0.25);
            transform: translateY(-2px);
        }

        .container {
            display: flex;
            flex: 1;
            padding: 20px;
            max-width: 1600px;
            margin: 0 auto;
            width: 100%;
            gap: 20px;
        }

        .sidebar {
            width: 260px;
            background: white;
            border-radius: 15px;
            padding: 20px 15px;
            box-shadow: 0 5px 15px rgba(0, 0, 0, 0.08);
            height: fit-content;
        }

        .sidebar-header {
            padding: 15px 10px;
            border-bottom: 1px solid #eaeaea;
            margin-bottom: 20px;
            display: flex;
            align-items: center;
            gap: 12px;
        }

        .sidebar-header i {
            font-size: 1.4rem;
            color: #3498db;
        }

        .sidebar-header h2 {
            color: #2c3e50;
            font-size: 1.4rem;
            font-weight: 600;
        }

        .sidebar ul {
            list-style: none;
            padding: 0;
        }

        .sidebar ul li {
            margin: 10px 0;
        }

        .sidebar ul li a {
            text-decoration: none;
            color: #555;
            display: flex;
            align-items: center;
            gap: 15px;
            padding: 14px 20px;
            border-radius: 10px;
            transition: all 0.3s ease;
            font-size: 1.1rem;
            font-weight: 500;
        }

        .sidebar ul li a:hover {
            background: #f0f7ff;
            color: #3498db;
        }

        .sidebar ul li a.active {
            background: #e1f0ff;
            color: #2980b9;
            font-weight: 600;
        }

        .sidebar ul li a i {
            font-size: 1.2rem;
            width: 25px;
            text-align: center;
        }

        .main-content {
            flex: 1;
            background: white;
            border-radius: 15px;
            padding: 30px;
            box-shadow: 0 5px 15px rgba(0, 0, 0, 0.08);
            display: flex;
            flex-direction: column;
            gap: 30px;
        }

        .welcome-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 10px;
            padding-bottom: 20px;
            border-bottom: 1px solid #eaeaea;
        }

        .welcome-header h2 {
            color: #2c3e50;
            font-size: 1.8rem;
            display: flex;
            align-items: center;
            gap: 15px;
        }

        .welcome-header h2 i {
            color: #3498db;
            background: #e1f0ff;
            width: 50px;
            height: 50px;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 1.5rem;
        }

        .section {
            background: white;
            border-radius: 12px;
            padding: 25px;
            box-shadow: 0 3px 10px rgba(0, 0, 0, 0.05);
            border: 1px solid #eaeaea;
        }

        .section-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 20px;
        }

        .section-header h3 {
            color: #2c3e50;
            font-size: 1.5rem;
            display: flex;
            align-items: center;
            gap: 12px;
        }

        .action-btn {
            background: #3498db;
            color: white;
            border: none;
            padding: 10px 20px;
            border-radius: 25px;
            cursor: pointer;
            font-weight: 500;
            display: flex;
            align-items: center;
            gap: 8px;
            transition: all 0.3s ease;
        }

        .action-btn:hover {
            background: #2980b9;
            transform: translateY(-2px);
        }

        .dashboard {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
            gap: 20px;
            margin: 25px 0;
        }

        .card {
            background: white;
            border-radius: 12px;
            padding: 25px;
            box-shadow: 0 3px 8px rgba(0, 0, 0, 0.05);
            transition: all 0.3s ease;
            border: 1px solid #eaeaea;
        }

        .card:hover {
            transform: translateY(-5px);
            box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
            border-color: #cce5ff;
        }

        .card h3 {
            color: #2c3e50;
            margin-top: 0;
            margin-bottom: 20px;
            font-size: 1.4rem;
            display: flex;
            align-items: center;
            gap: 10px;
            padding-bottom: 10px;
            border-bottom: 1px solid #f0f7ff;
        }

        .card h3 i {
            color: #3498db;
        }

        .card p {
            color: #555;
            line-height: 1.6;
            margin: 10px 0;
        }

        .card button {
            background: #e1f0ff;
            color: #2980b9;
            border: none;
            padding: 10px 20px;
            border-radius: 25px;
            cursor: pointer;
            font-weight: 500;
            margin-top: 15px;
            display: flex;
            align-items: center;
            gap: 8px;
            transition: all 0.3s ease;
            width: 100%;
            justify-content: center;
        }

        .card button:hover {
            background: #3498db;
            color: white;
        }

        .data-table {
            width: 100%;
            border-collapse: separate;
            border-spacing: 0;
            border-radius: 10px;
            overflow: hidden;
            box-shadow: 0 3px 8px rgba(0, 0, 0, 0.05);
            background: white;
            border: 1px solid #eaeaea;
            margin-top: 15px;
        }

        .data-table th {
            background: #3498db;
            color: white;
            padding: 16px 15px;
            text-align: left;
            font-weight: 500;
        }

        .data-table th:first-child {
            border-top-left-radius: 10px;
        }

        .data-table th:last-child {
            border-top-right-radius: 10px;
        }

        .data-table td {
            padding: 14px 15px;
            border-bottom: 1px solid #f0f7ff;
            color: #555;
        }

        .data-table tr:last-child td {
            border-bottom: none;
        }

        .data-table tr:nth-child(even) {
            background-color: #f9fcff;
        }

        .data-table tr:hover {
            background-color: #f0f7ff;
        }

        .data-table .status-badge {
            padding: 5px 12px;
            border-radius: 20px;
            font-size: 0.85rem;
            font-weight: 500;
        }

        .status-pending {
            background-color: #fff8e6;
            color: #f39c12;
        }

        .status-submitted {
            background-color: #e6f7e9;
            color: #27ae60;
        }

        .data-table button {
            background: #e1f0ff;
            color: #2980b9;
            border: none;
            padding: 8px 15px;
            border-radius: 20px;
            cursor: pointer;
            font-weight: 500;
            display: flex;
            align-items: center;
            gap: 6px;
            transition: all 0.3s ease;
        }

        .data-table button:hover {
            background: #3498db;
            color: white;
        }

        .grade-badge {
            display: inline-block;
            padding: 5px 12px;
            border-radius: 20px;
            font-weight: 600;
            background: #e1f0ff;
            color: #2980b9;
        }

        .progress-bar {
            height: 6px;
            background: #e0edf8;
            border-radius: 3px;
            overflow: hidden;
            margin-top: 5px;
        }

        .progress {
            height: 100%;
            background: #3498db;
            border-radius: 3px;
        }

        .loading-container {
            display: flex;
            justify-content: center;
            align-items: center;
            height: 200px;
        }

        .loading-spinner {
            width: 50px;
            height: 50px;
            border: 5px solid rgba(52, 152, 219, 0.3);
            border-radius: 50%;
            border-top-color: #3498db;
            animation: spin 1s ease-in-out infinite;
        }

        @keyframes spin {
            to {
                transform: rotate(360deg);
            }
        }

        .experiment-tabs {
            display: flex;
            background: white;
            border-radius: 10px;
            overflow: hidden;
            box-shadow: 0 4px 15px rgba(0, 0, 0, 0.08);
            margin-bottom: 30px;
        }

        .tab-btn {
            flex: 1;
            padding: 18px 20px;
            background: #f8f9fa;
            border: none;
            font-size: 1.1rem;
            font-weight: 600;
            cursor: pointer;
            transition: all 0.3s ease;
            border-bottom: 3px solid transparent;
        }

        .tab-btn:hover {
            background: #e9ecef;
        }

        .tab-btn.active {
            background: white;
            border-bottom: 3px solid #3498db;
            color: #3498db;
        }

        .tab-content {
            display: none;
            background: white;
            border-radius: 0 0 10px 10px;
            padding: 30px;
            box-shadow: 0 4px 15px rgba(0, 0, 0, 0.08);
        }

        .tab-content.active {
            display: block;
            animation: fadeIn 0.5s ease;
        }

        @keyframes fadeIn {
            from {
                opacity: 0;
                transform: translateY(10px);
            }

            to {
                opacity: 1;
                transform: translateY(0);
            }
        }

        .experiment-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 25px;
            padding-bottom: 15px;
            border-bottom: 1px solid #dee2e6;
        }

        .experiment-header h2 {
            font-size: 1.8rem;
            color: #2c3e50;
        }

        .status-badge {
            padding: 6px 15px;
            border-radius: 20px;
            font-size: 0.9rem;
            font-weight: 600;
        }

        .status-active {
            background-color: rgba(40, 167, 69, 0.15);
            color: #28a745;
        }

        .status-pending {
            background-color: rgba(255, 193, 7, 0.15);
            color: #ffc107;
        }

        .experiment-grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
            gap: 25px;
            margin-bottom: 30px;
        }

        .experiment-card {
            background: #f8f9fa;
            border-radius: 10px;
            padding: 25px;
            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.03);
            transition: transform 0.3s ease, box-shadow 0.3s ease;
            border-left: 4px solid #3498db;
        }

        .experiment-card:hover {
            transform: translateY(-5px);
            box-shadow: 0 6px 15px rgba(0, 0, 0, 0.1);
        }

        .experiment-card h3 {
            font-size: 1.3rem;
            margin-bottom: 15px;
            color: #2c3e50;
        }

        .experiment-card p {
            color: #666;
            margin-bottom: 20px;
            min-height: 60px;
        }

        .card-meta {
            display: flex;
            justify-content: space-between;
            font-size: 0.85rem;
            color: #777;
            margin-bottom: 20px;
        }

        .btn-group {
            display: flex;
            gap: 12px;
            margin-top: 15px;
            flex-wrap: wrap;
        }

        .btn {
            padding: 10px 18px;
            border: none;
            border-radius: 6px;
            font-weight: 600;
            cursor: pointer;
            transition: all 0.2s ease;
            font-size: 0.95rem;
            display: inline-flex;
            align-items: center;
            gap: 8px;
        }

        .btn-primary {
            background-color: #3498db;
            color: white;
        }

        .btn-primary:hover {
            background-color: #2980b9;
        }

        .btn-outline {
            background: transparent;
            border: 1px solid #3498db;
            color: #3498db;
        }

        .btn-outline:hover {
            background-color: rgba(52, 152, 219, 0.1);
        }

        .btn-success {
            background-color: #28a745;
            color: white;
        }

        .btn-success:hover {
            background-color: #218838;
        }

        .btn-warning {
            background-color: #ffc107;
            color: #333;
        }

        .btn-warning:hover {
            background-color: #e0a800;
        }

        .progress-container {
            margin: 25px 0;
        }

        .progress-bar {
            height: 10px;
            background-color: #e9ecef;
            border-radius: 5px;
            overflow: hidden;
            margin-top: 10px;
        }

        .progress-fill {
            height: 100%;
            background-color: #3498db;
            border-radius: 5px;
        }

        .progress-text {
            display: flex;
            justify-content: space-between;
            font-size: 0.9rem;
            color: #666;
        }

        .submission-section {
            background: #f8f9fa;
            border-radius: 10px;
            padding: 25px;
            margin-top: 30px;
        }

        .submission-section h3 {
            margin-bottom: 20px;
            color: #2c3e50;
        }

        .upload-area {
            border: 2px dashed #dee2e6;
            border-radius: 8px;
            padding: 30px;
            text-align: center;
            margin-bottom: 20px;
            transition: all 0.3s ease;
            cursor: pointer;
        }

        .upload-area:hover {
            border-color: #3498db;
            background-color: rgba(52, 152, 219, 0.03);
        }

        .upload-area i {
            font-size: 3rem;
            color: #adb5bd;
            margin-bottom: 15px;
            display: block;
        }

        .upload-indicator {
            position: fixed;
            bottom: 20px;
            left: 20px;
            background: #3498db;
            color: white;
            padding: 15px 25px;
            border-radius: 8px;
            box-shadow: 0 4px 15px rgba(0, 0, 0, 0.15);
            display: flex;
            align-items: center;
            gap: 15px;
            z-index: 1000;
            animation: slideIn 0.3s ease-out;
        }

        .upload-progress {
            height: 6px;
            background: rgba(255, 255, 255, 0.3);
            border-radius: 3px;
            margin-top: 8px;
            overflow: hidden;
        }

        .upload-progress-fill {
            height: 100%;
            background: white;
            border-radius: 3px;
            transition: width 0.3s ease;
        }

        .file-list {
            margin-top: 20px;
            background: white;
            border-radius: 8px;
            padding: 15px;
            border: 1px solid #eee;
        }

        .file-item {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 10px;
            border-bottom: 1px solid #f0f0f0;
        }

        .file-item:last-child {
            border-bottom: none;
        }

        .file-name {
            display: flex;
            align-items: center;
            gap: 10px;
        }

        .file-actions {
            display: flex;
            gap: 10px;
        }

        .file-actions button {
            background: none;
            border: none;
            cursor: pointer;
            color: #e74c3c;
            font-size: 1.1rem;
        }

        .error-message {
            background-color: #f8d7da;
            color: #721c24;
            padding: 15px;
            border-radius: 5px;
            margin: 20px 0;
            border: 1px solid #f5c6cb;
            text-align: center;
        }

        .retry-btn {
            background: #dc3545;
            color: white;
            border: none;
            padding: 8px 15px;
            border-radius: 4px;
            cursor: pointer;
            margin-top: 10px;
            display: inline-block;
        }

        .retry-btn:hover {
            background: #c82333;
        }

        .experiment-table-section {
            margin-top: 30px;
        }

        .experiment-table-section .section-header {
            margin-bottom: 15px;
        }

        .modal-overlay {
            position: fixed;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background: rgba(0, 0, 0, 0.5);
            display: flex;
            justify-content: center;
            align-items: center;
            z-index: 2000;
        }

        .modal-content {
            background: white;
            border-radius: 15px;
            width: 90%;
            max-width: 700px;
            max-height: 90vh;
            overflow-y: auto;
            box-shadow: 0 5px 25px rgba(0, 0, 0, 0.2);
            animation: modalFadeIn 0.3s ease;
        }

        @keyframes modalFadeIn {
            from {
                opacity: 0;
                transform: translateY(-20px);
            }

            to {
                opacity: 1;
                transform: translateY(0);
            }
        }

        .modal-header {
            padding: 20px;
            border-bottom: 1px solid #eee;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }

        .modal-header h3 {
            color: #2c3e50;
            font-size: 1.5rem;
            display: flex;
            align-items: center;
            gap: 10px;
        }

        .close-btn {
            background: none;
            border: none;
            font-size: 1.5rem;
            cursor: pointer;
            color: #777;
            transition: color 0.3s;
        }

        .close-btn:hover {
            color: #e74c3c;
        }

        .modal-body {
            padding: 20px;
        }

        .requirement-section {
            background: #f9f9ff;
            border-radius: 10px;
            padding: 20px;
            margin-bottom: 25px;
            border: 1px solid #e0e0ff;
        }

        .requirement-section h4 {
            margin-bottom: 15px;
            color: #3498db;
            display: flex;
            align-items: center;
            gap: 10px;
        }

        .requirement-list {
            padding-left: 20px;
        }

        .requirement-list li {
            margin-bottom: 8px;
            color: #555;
        }

        .file-list {
            margin-top: 20px;
            background: white;
            border-radius: 8px;
            padding: 15px;
            border: 1px solid #eee;
            max-height: 250px;
            overflow-y: auto;
        }

        .file-item {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 10px;
            border-bottom: 1px solid #f0f0f0;
        }

        .file-item:last-child {
            border-bottom: none;
        }

        .file-name {
            display: flex;
            align-items: center;
            gap: 10px;
            max-width: 70%;
            overflow: hidden;
            text-overflow: ellipsis;
        }

        .file-actions {
            display: flex;
            gap: 10px;
        }

        .file-actions button {
            background: none;
            border: none;
            cursor: pointer;
            color: #e74c3c;
            font-size: 1.1rem;
        }

        .modal-footer {
            padding: 20px;
            display: flex;
            justify-content: flex-end;
            gap: 15px;
            border-top: 1px solid #eee;
        }

        .modal-btn {
            padding: 12px 25px;
            border-radius: 6px;
            font-weight: 600;
            cursor: pointer;
            transition: all 0.2s ease;
            display: inline-flex;
            align-items: center;
            gap: 8px;
            border: none;
        }

        .btn-primary {
            background-color: #3498db;
            color: white;
        }

        .btn-primary:hover {
            background-color: #2980b9;
        }

        .btn-outline {
            background: transparent;
            border: 1px solid #3498db;
            color: #3498db;
        }

        .btn-outline:hover {
            background-color: rgba(52, 152, 219, 0.1);
        }

        .btn-success {
            background-color: #28a745;
            color: white;
        }

        .btn-success:hover {
            background-color: #218838;
        }

        .btn-danger {
            background-color: #e74c3c;
            color: white;
        }

        .btn-danger:hover {
            background-color: #c0392b;
        }

        .course-grade-card {
            background: white;
            border-radius: 10px;
            padding: 20px;
            margin-bottom: 20px;
            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
            border-left: 3px solid #3498db;
        }

        .course-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 15px;
            padding-bottom: 10px;
            border-bottom: 1px solid #f0f7ff;
        }

        .course-header h3 {
            font-size: 1.3rem;
            color: #2c3e50;
        }

        .course-id {
            font-size: 0.9rem;
            color: #777;
            background: #f0f7ff;
            padding: 4px 8px;
            border-radius: 4px;
        }

        .experiment-grade {
            margin-bottom: 15px;
            padding: 12px;
            background: #f9fcff;
            border-radius: 8px;
        }

        .experiment-header {
            display: flex;
            justify-content: space-between;
            margin-bottom: 8px;
        }

        .experiment-title {
            font-weight: 500;
            display: flex;
            align-items: center;
            gap: 8px;
        }

        .experiment-score {
            font-weight: 600;
            color: #2980b9;
            font-size: 1.1rem;
        }

        .grade-details {
            display: grid;
            grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
            gap: 10px;
        }

        .grade-part {
            display: flex;
            justify-content: space-between;
            font-size: 0.95rem;
            padding: 8px;
            background: white;
            border-radius: 6px;
            border: 1px solid #eaeaea;
        }

        .part-name {
            color: #555;
        }

        .part-score {
            font-weight: 500;
            color: #3498db;
            margin: 0 8px;
        }

        .part-weight {
            color: #888;
            font-size: 0.85rem;
        }

        .download-notification {
            position: fixed;
            bottom: 20px;
            right: 20px;
            background: #27ae60;
            color: white;
            padding: 15px 25px;
            border-radius: 8px;
            box-shadow: 0 4px 15px rgba(0, 0, 0, 0.15);
            display: flex;
            align-items: center;
            gap: 10px;
            z-index: 1000;
            animation: slideIn 0.3s ease-out;
        }

        @keyframes slideIn {
            from {
                transform: translateX(100%);
                opacity: 0;
            }

            to {
                transform: translateX(0);
                opacity: 1;
            }
        }

        @keyframes fadeIn {
            from {
                opacity: 0;
                transform: translateY(20px);
            }

            to {
                opacity: 1;
                transform: translateY(0);
            }
        }

        .card,
        .section,
        .experiment-card {
            animation: fadeIn 0.5s ease-out;
        }

        .card:nth-child(2) {
            animation-delay: 0.1s;
        }

        .card:nth-child(3) {
            animation-delay: 0.2s;
        }

        .section:nth-child(2) {
            animation-delay: 0.3s;
        }

        @media (max-width: 800px) {
            .container {
                flex-direction: column;
            }

            .sidebar {
                width: 100%;
                margin-bottom: 20px;
            }
        }

        @media (max-width: 768px) {
            .navbar {
                padding: 12px 15px;
            }

            .logo-container h1 {
                font-size: 1.5rem;
            }

            .welcome-header {
                flex-direction: column;
                align-items: flex-start;
                gap: 15px;
            }

            .section-header {
                flex-direction: column;
                align-items: flex-start;
                gap: 15px;
            }

            .action-btn {
                width: 100%;
                justify-content: center;
            }

            .dashboard {
                grid-template-columns: 1fr;
            }

            .experiment-tabs {
                flex-direction: column;
            }

            .experiment-grid {
                grid-template-columns: 1fr;
            }

            .modal-content {
                width: 95%;
                max-height: 85vh;
            }

            .modal-footer {
                flex-direction: column;
                gap: 10px;
            }

            .modal-btn {
                width: 100%;
                justify-content: center;
            }
        }
    </style>
</head>

<body>
    <div id="app">
        <!-- 顶部导航栏 -->
        <div class="navbar">
            <div class="logo-container">
                <img src=""
                    alt="LOGO">
                <h1>学生实验管理系统</h1>
            </div>

            <div class="user-info-container">
                <div class="user-avatar" @click="toggleDropdown">{{ user.name.charAt(0) }}</div>
                <div class="dropdown-menu" :class="{show: isDropdownOpen}">
                    <div class="dropdown-header">
                        <h4>{{ user.name }}</h4>
                        <p>{{ user.class }}</p>
                    </div>
                    <div class="dropdown-item" @click="editProfile">
                        <i class="fas fa-user-edit"></i>编辑个人信息
                    </div>
                    <div class="dropdown-item" @click="changePassword">
                        <i class="fas fa-key"></i>修改密码
                    </div>
                    <div class="dropdown-divider"></div>
                    <div class="dropdown-item" @click="logout">
                        <i class="fas fa-sign-out-alt"></i>退出登录
                    </div>
                </div>
                <button class="logout-btn" @click="logout">
                    <i class="fas fa-sign-out-alt"></i> 退出
                </button>
            </div>
        </div>

        <!-- 页面容器 -->
        <div class="container">
            <!-- 侧边栏 -->
            <div class="sidebar">
                <div class="sidebar-header">
                    <i class="fas fa-user-graduate"></i>
                    <h2>学生控制台</h2>
                </div>
                <ul>
                    <li v-for="item in menuItems" :key="item.id">
                        <a href="#" :class="{active: activeMenu === item.id}" @click.prevent="setActiveMenu(item.id)">
                            <i :class="item.icon"></i>{{ item.name }}
                        </a>
                    </li>
                </ul>
            </div>

            <!-- 主内容区 -->
            <div class="main-content">
                <!-- 仪表盘页面 -->
                <div v-if="activeMenu === 'dashboard' && !loading && !error">
                    <div class="welcome-header">
                        <h2>
                            <i class="fas fa-user-graduate"></i>
                            欢迎回来，{{ user.name }}
                        </h2>
                    </div>

                    <!-- 仪表盘 - 保留个人信息和学习状态卡片 -->
                    <div class="section">
                        <div class="section-header">
                            <h3><i class="fas fa-tachometer-alt"></i> 学生仪表盘</h3>
                        </div>

                        <div class="dashboard">
                            <div class="card">
                                <h3><i class="fas fa-user"></i> 个人信息</h3>
                                <p><strong>姓名：</strong>{{ user.name }}</p>
                                <p><strong>班级：</strong>{{ user.class }}</p>
                                <p><strong>学号：</strong>{{ user.studentId }}</p>
                                <button @click="editProfile">
                                    <i class="fas fa-edit"></i>编辑个人信息
                                </button>
                            </div>

                            <div class="card">
                                <h3><i class="fas fa-tasks"></i> 学习状态</h3>
                                <p><i class="fas fa-envelope"></i> 未读通知：<strong>{{ unreadNotifications }}条</strong></p>
                                <p><i class="fas fa-file-signature"></i> 待提交作业：<strong>{{ pendingExperimentsCount
                                        }}份</strong></p>
                                <p><i class="fas fa-check-circle"></i> 已完成实验：<strong>{{ completedExperimentsCount
                                        }}个</strong></p>
                                <div class="progress-bar">
                                    <div class="progress" :style="{width: progressPercentage + '%'}"></div>
                                </div>
                                <p class="progress-text">整体进度：{{ progressPercentage }}%</p>
                            </div>
                        </div>
                    </div>
                </div>

                <!-- 实验查看页面 -->
                <div v-if="activeMenu === 'experiment' && !loading && !error">
                    <div class="welcome-header">
                        <h2>
                            <i class="fas fa-flask"></i>
                            实验中心
                        </h2>
                    </div>

                    <div class="experiment-tabs">
                        <button class="tab-btn" :class="{active: activeTab === 'all'}"
                            @click="activeTab = 'all'">所有实验</button>
                        <button class="tab-btn" :class="{active: activeTab === 'active'}"
                            @click="activeTab = 'active'">进行中</button>
                        <button class="tab-btn" :class="{active: activeTab === 'completed'}"
                            @click="activeTab = 'completed'">已完成</button>
                        <button class="tab-btn" :class="{active: activeTab === 'resources'}"
                            @click="activeTab = 'resources'">资源中心</button>
                    </div>

                    <!-- 所有实验 - 添加表格视图 -->
                    <div id="all-experiments" class="tab-content" :class="{active: activeTab === 'all'}">
                        <div class="experiment-header">
                            <h2>所有实验列表</h2>
                            <div class="status-badge status-active">当前学期</div>
                        </div>

                        <!-- 添加实验进度信息 -->
                        <div class="progress-container">
                            <div class="progress-text">
                                <span>整体进度</span>
                                <span>{{ progressPercentage }}%</span>
                            </div>
                            <div class="progress-bar">
                                <div class="progress-fill" :style="{width: progressPercentage + '%'}"></div>
                            </div>
                        </div>

                        <!-- 实验任务列表表格 -->
                        <div class="experiment-table-section">
                            <div class="section">
                                <div class="section-header">
                                    <h3><i class="fas fa-table"></i> 实验任务列表</h3>
                                    <button class="action-btn" @click="refreshExperiments">
                                        <i class="fas fa-sync-alt"></i> 刷新列表
                                    </button>
                                </div>

                                <table class="data-table">
                                    <thead>
                                        <tr>
                                            <th>实验编号</th>
                                            <th>实验名称</th>
                                            <th>截止时间</th>
                                            <th>提交状态</th>
                                            <th>成绩</th>
                                            <th>操作</th>
                                        </tr>
                                    </thead>
                                    <tbody>
                                        <tr v-for="exp in experiments" :key="exp.id">
                                            <td>
                                                <a :href="exp.link">{{ exp.id }}</a>
                                            </td>
                                            <td>{{ exp.name }}</td>
                                            <td>{{ exp.deadline }}</td>
                                            <td>
                                                <span class="status-badge" :class="exp.statusClass">
                                                    {{ exp.statusText }}
                                                </span>
                                                <div class="progress-bar" v-if="exp.status === 'pending'">
                                                    <div class="progress" :style="{width: exp.progress + '%'}"></div>
                                                </div>
                                            </td>
                                            <td>
                                                <span class="grade-badge" v-if="exp.grade">{{ exp.grade }}</span>
                                                <span v-else>-</span>
                                            </td>
                                            <td>
                                                <button v-if="exp.status === 'submitted'"
                                                    @click="handleExperimentAction('view', exp)">
                                                    <i class="fas fa-eye"></i>查看详情
                                                </button>
                                                <button v-else @click="openSubmissionModal(exp)">
                                                    <i class="fas fa-file-upload"></i>提交作业
                                                </button>
                                                <div class="upload-indicator" v-if="uploadStatus.visible">
                                                    <i class="fas fa-cloud-upload-alt"></i>
                                                    <div>
                                                        <div>{{ uploadStatus.message }}</div>
                                                        <div class="upload-progress">
                                                            <div class="upload-progress-fill"
                                                                :style="{width: uploadStatus.progress + '%'}"></div>
                                                        </div>
                                                    </div>
                                                </div>
                                            </td>
                                        </tr>
                                    </tbody>
                                </table>
                            </div>
                        </div>
                    </div>

                    <!-- 进行中实验 -->
                    <div id="active-experiments" class="tab-content" :class="{active: activeTab === 'active'}">
                        <div class="experiment-header">
                            <h2>进行中的实验</h2>
                            <div class="status-badge status-active">{{ pendingExperimentsCount }}个实验</div>
                        </div>

                        <div class="experiment-grid">
                            <div class="experiment-card" v-for="exp in pendingExperiments" :key="exp.id">
                                <h3>{{ exp.name }}</h3>
                                <p>{{ exp.description }}</p>
                                <div class="card-meta">
                                    <span><i class="far fa-calendar"></i> 截止: {{ exp.deadline }}</span>
                                    <span><i class="far fa-clock"></i> 剩余: {{ exp.daysLeft }}天</span>
                                </div>
                                <div class="btn-group">
                                    <button class="btn btn-warning" @click="continueExperiment(exp)"><i
                                            class="fas fa-edit"></i> 继续实验</button>
                                    <button class="btn btn-primary" @click="downloadExperimentResources(exp)"><i
                                            class="fas fa-download"></i> 资料</button>
                                    <button class="btn btn-primary" @click="downloadReportTemplate(exp)"><i
                                            class="fas fa-file-download"></i> 模板</button>
                                </div>
                            </div>
                        </div>

                        <div class="submission-section">
                            <h3>提交实验结果</h3>
                            <p>请根据实验要求提交您的实验结果和报告：</p>
                            <div v-if="uploadError" class="error-message">
                                <p>提交失败: {{ uploadError }}</p>
                            </div>

                            <div class="upload-area" @click="openFilePicker" @dragover.prevent="handleDragOver"
                                @dragleave.prevent="handleDragLeave" @drop.prevent="handleDrop($event, 'page')">
                                <i class="fas fa-cloud-upload-alt"></i>
                                <p>拖放文件到此处或点击上传</p>
                                <p class="small">支持格式: .zip, .pdf, .docx (最大: 50MB)</p>
                                <input type="file" id="fileInput" multiple style="display: none"
                                    @change="handleFileUpload">
                            </div>

                            <div class="file-list" v-if="uploadedFiles.length > 0">
                                <h4>已选择文件：</h4>
                                <div class="file-item" v-for="(file, index) in uploadedFiles" :key="index">
                                    <div class="file-name">
                                        <i class="fas fa-file"></i>
                                        <span>{{ file.name }}</span>
                                    </div>
                                    <div class="file-actions">
                                        <button @click="removeFile(index)"><i class="fas fa-trash"></i></button>
                                    </div>
                                </div>
                            </div>

                            <div class="btn-group" style="margin-top: 20px;">
                                <button class="btn btn-success" @click="submitExperiment"><i
                                        class="fas fa-check-circle"></i> 提交结果</button>
                                <button class="btn btn-success" @click="submitReport"><i
                                        class="fas fa-file-signature"></i> 提交报告</button>
                            </div>
                        </div>
                    </div>

                    <!-- 已完成实验 -->
                    <div id="completed-experiments" class="tab-content" :class="{active: activeTab === 'completed'}">
                        <div class="experiment-header">
                            <h2>已完成的实验</h2>
                            <div class="status-badge status-active">{{ completedExperimentsCount }}个实验</div>
                        </div>

                        <div class="experiment-grid">
                            <div class="experiment-card" v-for="exp in completedExperiments" :key="exp.id">
                                <h3>{{ exp.name }}</h3>
                                <p>{{ exp.description }}</p>
                                <div class="card-meta">
                                    <span><i class="fas fa-check-circle"></i> 已完成</span>
                                    <span><i class="fas fa-star"></i> 评分: {{ exp.grade }}/100</span>
                                </div>
                                <div class="btn-group">
                                    <button class="btn btn-outline" @click="viewSubmission(exp)"><i
                                            class="fas fa-eye"></i> 查看提交</button>
                                    <button class="btn btn-outline" @click="viewFeedback(exp)"><i
                                            class="fas fa-comment-alt"></i> 教师反馈</button>
                                    <button class="btn btn-primary" @click="downloadExperimentResources(exp)"><i
                                            class="fas fa-download"></i> 资料</button>
                                </div>
                            </div>
                        </div>
                    </div>

                    <!-- 资源中心 -->
                    <div id="resources" class="tab-content" :class="{active: activeTab === 'resources'}">
                        <div class="experiment-header">
                            <h2>实验资源中心</h2>
                            <div class="status-badge status-active">下载资料与模板</div>
                        </div>

                        <div class="experiment-grid">
                            <div class="experiment-card" v-for="exp in experiments" :key="exp.id">
                                <h3>{{ exp.name }}资源</h3>
                                <p>{{ exp.name }}所需的所有材料和模板</p>
                                <div class="btn-group">
                                    <!-- 动态生成资源按钮 -->
                                    <button v-for="res in exp.resources" :key="res.id" class="btn btn-primary"
                                        @click="downloadResource(exp.id, res.id, res.name)">
                                        <i :class="getResourceIcon(res.type)"></i> {{ res.name }}
                                    </button>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>

                <!-- 成绩查询页面 -->
                <div v-if="activeMenu === 'grades' && !loading">
                    <div class="welcome-header">
                        <h2><i class="fas fa-chart-line"></i> 成绩查询</h2>
                    </div>

                    <div class="section">
                        <div v-for="course in courseGrades" :key="course.courseId" class="course-grade-card">
                            <div class="course-header">
                                <h3>{{ course.courseName }}</h3>
                                <span class="course-id">课程ID: {{ course.courseId }}</span>
                            </div>

                            <div class="experiment-grades">
                                <div v-for="(exp, idx) in course.experimentGrades" :key="idx" class="experiment-grade">
                                    <div class="experiment-header">
                                        <h4>
                                            <i class="fas fa-flask"></i>
                                            实验{{ idx+1 }}: {{ exp.title }}
                                        </h4>
                                    </div>

                                    <div class="grade-details">
                                        <div v-for="(part, pIdx) in exp.parts" :key="pIdx" class="grade-part">
                                            <div class="part-info">
                                                <span class="part-name">{{ part.partName }}</span>
                                                <span class="part-score">{{ part.score }}分</span>
                                                <span class="part-max">(满分: {{ part.maxScore }}分)</span>
                                            </div>
                                            <div class="part-weight">权重: {{ (part.weight * 100).toFixed(0) }}%</div>
                                            <div class="progress-bar">
                                                <div class="progress-fill"
                                                    :style="{width: (part.score / part.maxScore * 100) + '%'}"></div>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>

            </div>
        </div>

        <!-- 提交作业模态框 -->
        <div v-if="showSubmissionModal" class="modal-overlay" @click.self="closeSubmissionModal">
            <div class="modal-content">
                <div class="modal-header">
                    <h3><i class="fas fa-file-upload"></i> 提交作业 - {{ currentExperiment.name }}</h3>
                    <button class="close-btn" @click="closeSubmissionModal">
                        <i class="fas fa-times"></i>
                    </button>
                </div>

                <div class="modal-body">
                    <div class="requirement-section">
                        <h4><i class="fas fa-info-circle"></i> 提交要求</h4>
                        <ul class="requirement-list">
                            <li>实验编号: <strong>{{ currentExperiment.id }}</strong></li>
                            <li>截止时间: <strong>{{ currentExperiment.deadline }}</strong></li>
                            <li>文件格式: {{ currentExperiment.fileFormats || 'PDF, DOCX, ZIP' }}</li>
                            <li>命名规则: {{ currentExperiment.namingRule || '学号_姓名_实验编号_文件名' }}</li>
                            <li>最大文件大小: 50MB</li>
                            <li>最多可提交文件数: 5个</li>
                        </ul>
                    </div>

                    <div v-if="modalUploadError" class="error-message">
                        <p>{{ modalUploadError }}</p>
                    </div>

                    <div class="upload-area" @click="openModalFilePicker" @dragover.prevent="handleDragOver"
                        @dragleave.prevent="handleDragLeave" @drop.prevent="handleDrop($event, 'modal')">
                        <i class="fas fa-cloud-upload-alt"></i>
                        <p>拖放文件到此处或点击上传</p>
                        <p class="small">支持格式: {{ currentExperiment.fileFormats || 'PDF, DOCX, ZIP' }}</p>
                        <input type="file" id="modalFileInput" multiple style="display: none"
                            @change="handleModalFileUpload">
                    </div>


                    <div class="file-list" v-if="modalUploadedFiles.length > 0">
                        <h4>已选择文件：</h4>
                        <div class="file-item" v-for="(file, index) in modalUploadedFiles" :key="index">
                            <div class="file-name">
                                <i class="fas" :class="getFileIcon(file)"></i>
                                <span>{{ file.name }}</span>
                            </div>
                            <div class="file-actions">
                                <button @click="removeModalFile(index)">
                                    <i class="fas fa-trash"></i>
                                </button>
                            </div>
                        </div>
                    </div>
                </div>

                <div class="modal-footer">
                    <button class="modal-btn btn-outline" @click="closeSubmissionModal">
                        <i class="fas fa-times"></i> 取消
                    </button>
                    <button class="modal-btn btn-primary" @click="submitModalFiles"
                        :disabled="modalUploadedFiles.length === 0">
                        <i class="fas fa-paper-plane"></i> 提交作业
                    </button>
                </div>
            </div>
        </div>
        <div class="download-indicator" v-if="downloadStatus.visible" :class="{error: downloadStatus.error}">
            <i :class="downloadStatus.error ? 'fas fa-exclamation-triangle' : 'fas fa-download'"></i>
            <div>
                <div>{{ downloadStatus.message }}</div>
                <div class="download-progress">
                    <div class="download-progress-fill" :style="{width: downloadStatus.progress + '%'}"></div>
                </div>
            </div>
        </div>
    </div>

    <script>
        new Vue({
            el: '#app',
            data: {
                // 用户信息
                user: {
                    name: '王同学',
                    class: '计算机科学2023级1班',
                    studentId: '20230001'
                },
                // 菜单项
                menuItems: [
                    { id: 'dashboard', name: '仪表盘', icon: 'fas fa-tachometer-alt' },
                    { id: 'experiment', name: '实验中心', icon: 'fas fa-flask' },
                    { id: 'grades', name: '成绩查询', icon: 'fas fa-chart-line' },
                    { id: 'notices', name: '通知公告', icon: 'fas fa-bullhorn' },
                    { id: 'help', name: '帮助与反馈', icon: 'fas fa-question-circle' }
                ],
                activeMenu: 'dashboard',
                isDropdownOpen: false,
                activeTab: 'all',
                uploadedFiles: [],
                uploadError: null,
                experiments: [],
                loading: true,
                error: null,
                unreadNotifications: 1,

                // 提交作业模态框相关数据
                showSubmissionModal: false,
                currentExperiment: null,
                modalUploadedFiles: [],
                modalUploadError: null,

                // 下载状态
                downloadStatus: {
                    visible: false,
                    message: '',
                    progress: 0,
                    error: false
                },

                uploadStatus: {
                    visible: false,
                    message: '',
                    progress: 0
                },

                courseGrades: [],
                currentCourseGrade: null,
                selectedYear: new Date().getFullYear()
            },
            computed: {
                // 计算待提交的实验
                pendingExperiments() {
                    return this.experiments.filter(exp => exp.status === 'pending');
                },
                // 计算已完成的实验
                completedExperiments() {
                    return this.experiments.filter(exp => exp.status === 'submitted');
                },
                // 待提交实验数量
                pendingExperimentsCount() {
                    return this.pendingExperiments.length;
                },
                // 已完成实验数量
                completedExperimentsCount() {
                    return this.completedExperiments.length;
                },
                // 计算整体进度
                progressPercentage() {
                    const completed = this.completedExperimentsCount;
                    const total = this.experiments.length;
                    return total > 0 ? Math.round((completed / total) * 100) : 0;
                }
            },
            created() {
                this.loadUserFromSession();
                // 组件创建时加载实验数据
                this.loadExperiments();

                // 在组件创建时加载成绩
                if (this.activeMenu === 'grades') {
                    this.loadGrades();
                }
            },
            methods: {
                // 从会话中加载用户信息
                loadUserFromSession() {
                    // 兼容不同key的用户信息
                    let sessionUser = null;
                    if (sessionStorage.getItem('userInfo')) {
                        sessionUser = JSON.parse(sessionStorage.getItem('userInfo'));
                        this.user.name = sessionUser.name;
                        this.user.studentId = sessionUser.id;
                        this.user.role = sessionUser.role;
                    }
                },

                // 从后端加载实验数据
                async loadExperiments() {
                    this.loading = true;
                    this.error = null;
                    try {
                        // 从本地存储获取 token
                        const token = localStorage.getItem('authToken') || sessionStorage.getItem('authToken');

                        if (!token) {
                            throw new Error('登录凭证已过期，请重新登录');
                        }

                        // 添加认证头
                        const response = await axios.get('/api/student/experiments', {
                            headers: {
                                Authorization: `Bearer ${token}`
                            }
                        });

                        try {
                            // 处理响应数据
                            this.experiments = response.data.experiments.map(exp => ({
                                ...exp,
                                statusClass: exp.status === 'submitted' ? 'status-submitted' : 'status-pending',
                                statusText: exp.status === 'submitted' ? '已提交' : '未提交',
                                daysLeft: this.calculateDaysLeft(exp.deadline),
                                // 添加文件格式和命名规则
                                fileFormats: exp.fileFormats || 'PDF, DOCX, ZIP',
                                namingRule: exp.namingRule || '学号_姓名_实验编号_文件名'
                            }));
                            console.log('resources:', response.data.experiments[0].resources);
                            console.log('实验数据:', response.data.experiments);
                        } catch (err) {
                            this.error = '无法加载实验数据: ' + (err.response?.data?.message || err.message);
                            console.error('获取实验数据失败:', err);
                        } finally {
                            this.loading = false;
                        }
                    } catch (err) {
                        // 处理 401 错误
                        if (err.response?.status === 401) {
                            this.error = '登录已过期，请重新登录';
                            setTimeout(() => window.location.href = '/login.html', 5000);
                        } else {
                            this.error = '无法加载实验数据: ' + (err.response?.data?.message || err.message);
                        }
                    } finally {
                        this.loading = false;
                    }
                },

                // 计算剩余天数
                calculateDaysLeft(deadline) {
                    const today = new Date();
                    const dueDate = new Date(deadline);
                    const diffTime = dueDate - today;
                    return Math.ceil(diffTime / (1000 * 60 * 60 * 24));
                },

                // 退出登录
                logout() {
                    localStorage.removeItem('authToken');
                    sessionStorage.removeItem('authToken');
                    window.location.href = '/login.html';
                },
                // 设置活动菜单
                setActiveMenu(menuId) {
                    this.activeMenu = menuId;
                },
                // 切换下拉菜单
                toggleDropdown() {
                    this.isDropdownOpen = !this.isDropdownOpen;
                },
                // 编辑个人信息
                editProfile() {
                    alert('编辑个人信息功能');
                    this.closeDropdown();
                },
                // 修改密码
                changePassword() {
                    alert('修改密码功能');
                    this.closeDropdown();
                },
                // 关闭下拉菜单
                closeDropdown() {
                    this.isDropdownOpen = false;
                },
                // 刷新实验列表
                refreshExperiments() {
                    this.loadExperiments();
                    alert('正在从后端刷新实验数据');
                },
                // 处理实验操作
                handleExperimentAction(action, experiment) {
                    if (action === 'view') {
                        alert(`查看实验详情: ${experiment.name}`);
                    } else {
                        this.openSubmissionModal(experiment);
                    }
                },

                // 打开提交作业模态框
                openSubmissionModal(experiment) {
                    this.currentExperiment = experiment;
                    this.modalUploadedFiles = [];
                    this.modalUploadError = null;
                    this.showSubmissionModal = true;
                },

                // 关闭提交作业模态框
                closeSubmissionModal() {
                    this.showSubmissionModal = false;
                    this.currentExperiment = null;
                    this.modalUploadedFiles = [];
                    this.modalUploadError = null;
                },

                // 打开模态框中的文件选择器
                openModalFilePicker() {
                    document.getElementById('modalFileInput').click();
                },

                // 添加拖拽事件处理方法
                handleDragOver(event) {
                    event.preventDefault();
                    event.stopPropagation();
                    event.currentTarget.style.borderColor = '#3498db';
                    event.currentTarget.style.backgroundColor = 'rgba(52, 152, 219, 0.1)';
                },

                handleDragLeave(event) {
                    event.preventDefault();
                    event.stopPropagation();
                    event.currentTarget.style.borderColor = '#dee2e6';
                    event.currentTarget.style.backgroundColor = '';
                },

                handleDrop(event, type) {
                    event.preventDefault();
                    event.stopPropagation();

                    // 恢复样式
                    const target = event.currentTarget;
                    target.style.borderColor = '#dee2e6';
                    target.style.backgroundColor = '';

                    const files = event.dataTransfer.files;
                    if (files.length === 0) return;

                    // 根据类型处理文件
                    if (type === 'modal') {
                        this.handleModalFiles(files);
                    } else {
                        this.handleFiles(files);
                    }
                },

                // 处理模态框文件
                handleModalFiles(fileList) {
                    const files = Array.from(fileList);
                    if (this.modalUploadedFiles.length + files.length > 5) {
                        this.modalUploadError = '最多只能上传5个文件';
                        return;
                    }

                    for (let i = 0; i < files.length; i++) {
                        if (files[i].size > 50 * 1024 * 1024) {
                            this.modalUploadError = `文件 ${files[i].name} 超过50MB大小限制`;
                            continue;
                        }
                        this.modalUploadedFiles.push(files[i]);
                    }
                },

                // 处理页面文件
                handleFiles(fileList) {
                    const files = Array.from(fileList);
                    for (let i = 0; i < files.length; i++) {
                        if (files[i].size > 50 * 1024 * 1024) {
                            this.uploadError = `文件 ${files[i].name} 超过50MB大小限制`;
                            continue;
                        }
                        this.uploadedFiles.push(files[i]);
                    }
                },

                // 处理模态框中的文件上传
                handleModalFileUpload(event) {
                    this.handleModalFiles(event.target.files);
                    event.target.value = '';
                },

                // 移除模态框中的文件
                removeModalFile(index) {
                    this.modalUploadedFiles.splice(index, 1);
                    this.modalUploadError = null;
                },

                // 获取文件图标
                getFileIcon(file) {
                    const ext = file.name.split('.').pop().toLowerCase();
                    switch (ext) {
                        case 'pdf': return 'fa-file-pdf';
                        case 'doc': case 'docx': return 'fa-file-word';
                        case 'xls': case 'xlsx': return 'fa-file-excel';
                        case 'zip': case 'rar': case '7z': return 'fa-file-archive';
                        case 'jpg': case 'jpeg': case 'png': case 'gif': return 'fa-file-image';
                        default: return 'fa-file';
                    }
                },

                // 提交模态框中的文件
                async submitModalFiles() {
                    try {
                        if (this.modalUploadedFiles.length === 0) {
                            this.modalUploadError = '请选择要提交的文件';
                            return;
                        }

                        const token = localStorage.getItem('authToken') || sessionStorage.getItem('authToken');
                        if (!token) {
                            throw new Error('登录凭证已过期，请重新登录');
                        }

                        const formData = new FormData();
                        formData.append('experimentId', this.currentExperiment.id);

                        // 添加所有文件
                        this.modalUploadedFiles.forEach(file => {
                            formData.append('files', file);
                        });

                        // 显示上传进度
                        this.showUploadProgress('正在提交文件...', 0);

                        // 发送请求
                        const response = await axios.post('/api/student/submit', formData, {
                            headers: {
                                Authorization: `Bearer ${token}`,
                                'Content-Type': 'multipart/form-data'
                            },
                            onUploadProgress: (progressEvent) => {
                                const percentCompleted = Math.round(
                                    (progressEvent.loaded * 100) / progressEvent.total
                                );
                                this.updateUploadProgress(percentCompleted);
                            }
                        });

                        // 提交成功后更新实验状态
                        const expIndex = this.experiments.findIndex(exp => exp.id === this.currentExperiment.id);
                        if (expIndex !== -1) {
                            this.$set(this.experiments[expIndex], 'status', 'submitted');
                            this.$set(this.experiments[expIndex], 'statusClass', 'status-submitted');
                            this.$set(this.experiments[expIndex], 'statusText', '已提交');
                        }

                        // 显示成功消息
                        this.showSuccessNotification(`实验 ${this.currentExperiment.name} 提交成功！`);
                        this.closeSubmissionModal();
                    } catch (error) {
                        let errorMsg = error.response?.data?.message || error.message || '提交失败';

                        // 处理特定错误
                        if (error.response?.status === 400) {
                            errorMsg = '验证失败: ' + errorMsg;
                        } else if (error.response?.status === 413) {
                            errorMsg = '文件太大，单个文件不能超过50MB';
                        }

                        this.modalUploadError = errorMsg;
                        console.error('提交失败:', error);
                    } finally {
                        this.hideUploadProgress();
                    }
                },

                // 打开文件选择器
                openFilePicker() {
                    document.getElementById('fileInput').click();
                },

                // 处理文件上传
                handleFileUpload(event) {
                    this.handleFiles(event.target.files);
                    event.target.value = '';
                },
                mounted() {
                    // 为模态框上传区域添加拖拽事件
                    const modalUploadArea = document.querySelector('.modal-content .upload-area');
                    if (modalUploadArea) {
                        modalUploadArea.addEventListener('dragover', this.handleDragOver);
                        modalUploadArea.addEventListener('dragleave', this.handleDragLeave);
                        modalUploadArea.addEventListener('drop', (e) => this.handleDrop(e, 'modal'));
                    }

                    // 为页面中的上传区域添加拖拽事件
                    const pageUploadArea = document.querySelector('.submission-section .upload-area');
                    if (pageUploadArea) {
                        pageUploadArea.addEventListener('dragover', this.handleDragOver);
                        pageUploadArea.addEventListener('dragleave', this.handleDragLeave);
                        pageUploadArea.addEventListener('drop', (e) => this.handleDrop(e, 'page'));
                    }
                },

                // 移除文件
                removeFile(index) {
                    this.uploadedFiles.splice(index, 1);
                },
                // 提交实验
                async submitExperiment() {
                    try {
                        if (this.uploadedFiles.length === 0) {
                            throw new Error('请选择要提交的文件');
                        }

                        const formData = new FormData();
                        this.uploadedFiles.forEach(file => {
                            formData.append('files', file);
                        });

                        await axios.post('/api/student/submissions', formData, {
                            headers: {
                                Authorization: `Bearer ${token}`,
                                'Content-Type': 'multipart/form-data'
                            }
                        });

                        this.uploadedFiles = [];
                        this.uploadError = null;
                        this.showSuccessNotification('提交成功！');
                    } catch (err) {
                        this.uploadError = err.response?.data?.message || err.message;
                    }
                },

                // 提交报告
                submitReport() {
                    this.submitExperiment();
                },

                // 添加方法
                showUploadProgress(message, progress = 0) {
                    this.uploadStatus = {
                        visible: true,
                        message: message,
                        progress: progress
                    };
                },

                updateUploadProgress(progress) {
                    if (this.uploadStatus.visible) {
                        this.uploadStatus.progress = progress;
                    }
                },

                hideUploadProgress() {
                    this.uploadStatus.visible = false;
                },

                // 查看实验详情
                viewExperimentDetails(experiment) {
                    alert(`查看实验详情: ${experiment.name}`);
                },
                // 继续实验
                continueExperiment(experiment) {
                    alert(`继续实验: ${experiment.name}`);
                },
                // 查看提交
                viewSubmission(experiment) {
                    alert(`查看提交: ${experiment.name}`);
                },
                // 查看反馈
                viewFeedback(experiment) {
                    alert(`查看教师反馈: ${experiment.name}`);
                },
                // 显示下载通知
                showDownloadNotification(message) {
                    const notification = document.createElement('div');
                    notification.className = 'download-notification';
                    notification.innerHTML = `
                        <i class="fas fa-download"></i>
                        <span>${message}</span>
                    `;
                    document.body.appendChild(notification);

                    setTimeout(() => {
                        document.body.removeChild(notification);
                    }, 3000);
                },

                // 显示成功通知
                showSuccessNotification(message) {
                    const notification = document.createElement('div');
                    notification.className = 'download-notification';
                    notification.style.background = '#27ae60';
                    notification.innerHTML = `
                        <i class="fas fa-check-circle"></i>
                        <span>${message}</span>
                    `;
                    document.body.appendChild(notification);

                    setTimeout(() => {
                        document.body.removeChild(notification);
                    }, 3000);
                },

                // 获取资源图标
                getResourceIcon(type) {
                    switch (type) {
                        case 'pdf': return 'fas fa-file-pdf';
                        case 'code': return 'fas fa-code';
                        default: return 'fas fa-file-download';
                    }
                },

                // 下载资源
                async downloadResource(expId, resId, resName) {
                    // 显示下载状态
                    this.showDownloadIndicator(`正在下载: ${resName}`, 0);

                    try {
                        // 获取认证token
                        const token = localStorage.getItem('authToken') || sessionStorage.getItem('authToken');
                        if (!token) {
                            throw new Error('登录凭证已过期，请重新登录');
                        }

                        // 构造API URL
                        const apiUrl = `/api/student/experiments/${expId}/resources/${resId}/download`;

                        // 发送下载请求
                        const response = await axios.get(apiUrl, {
                            headers: {
                                Authorization: `Bearer ${token}`
                            },
                            responseType: 'blob', // 重要：指定响应类型为二进制
                            onDownloadProgress: (progressEvent) => {
                                // 计算下载进度
                                const percentCompleted = Math.round(
                                    (progressEvent.loaded * 100) / progressEvent.total
                                );
                                this.updateDownloadIndicator(percentCompleted);
                            }
                        });

                        // 创建临时URL用于下载
                        const url = window.URL.createObjectURL(new Blob([response.data]));
                        const link = document.createElement('a');
                        link.href = url;
                        link.setAttribute('download', resName);
                        document.body.appendChild(link);

                        // 触发下载
                        link.click();

                        // 清理资源
                        setTimeout(() => {
                            document.body.removeChild(link);
                            window.URL.revokeObjectURL(url);
                        }, 100);

                        // 更新下载状态
                        this.showDownloadIndicator(`下载完成: ${resName}`, 100);
                        setTimeout(() => {
                            this.hideDownloadIndicator();
                        }, 2000);

                    } catch (error) {
                        console.error('下载失败:', error);
                        this.showDownloadIndicator(`下载失败: ${resName}`, 100, true);
                        setTimeout(() => {
                            this.hideDownloadIndicator();
                        }, 3000);
                    }
                },

                // 显示下载指示器
                showDownloadIndicator(message, progress = 0, isError = false) {
                    this.downloadStatus = {
                        visible: true,
                        message: message,
                        progress: progress,
                        error: isError
                    };
                },
                // 更新下载进度
                updateDownloadIndicator(progress) {
                    if (this.downloadStatus.visible) {
                        this.downloadStatus.progress = progress;
                    }
                },

                // 隐藏下载指示器
                hideDownloadIndicator() {
                    this.downloadStatus.visible = false;
                },

                // 加载成绩数据
                async loadGrades() {
                    try {
                        const token = localStorage.getItem('authToken') || sessionStorage.getItem('authToken');
                        // 直接请求成绩接口，无需参数
                        const response = await axios.get('/api/student/grades', {
                            headers: { Authorization: `Bearer ${token}` }
                        });
                        this.courseGrades = response.data;
                        console.log('加载的成绩数据:', this.courseGrades);
                    } catch (err) {
                        console.error('加载成绩失败:', err);
                    }
                },
                // 查看课程成绩详情
                async viewGradeDetail(courseId) {
                    try {
                        const token = localStorage.getItem('authToken') || sessionStorage.getItem('authToken');
                        const response = await axios.get(`/api/student/grades/${courseId}`, {
                            headers: { Authorization: `Bearer ${token}` }
                        });
                        this.currentCourseGrade = response.data;
                    } catch (err) {
                        console.error('获取成绩详情失败:', err);
                    }
                }
            },
            watch: {
                activeMenu(newVal) {
                    if (newVal === 'grades') {
                        this.loadGrades();
                    }
                }
            }
        });
    </script>
</body>

</html>